/*
 * CurvaBessier.cpp
 *
 *  Created on: 19/10/2013
 *      Author: ezequiel
 */

#include "CurvaBessier.h"
#include <math.h>
CurvaBessier::CurvaBessier(vector<glm::vec3> pControl, float divisiones) {
	this->divisiones = divisiones;
	this->pControl = pControl;
	t = 0;
	contAux = 0;
	tangAux.x = 0;
	tangAux.y = 0;
	tangAux.z = 0;
	tControl = new float[120];
//	cout << divisiones * 3 << endl;
	it = 0;
//	p[0] = this->pControl[0].x ;
//	p[1] = this->pControl[1].x ;
//	p[2] = this->pControl[2].x ;
//	p[3] = this->pControl[3].x ;

}


CurvaBessier::~CurvaBessier() {
	delete tControl;
}

glm::vec3 CurvaBessier::proximoPunto() {
	glm::vec3 puntoRetorno;
	float p[4];
	p[0] = this->pControl[0].x ;
	p[1] = this->pControl[1].x ;
	p[2] = this->pControl[2].x ;
	p[3] = this->pControl[3].x ;
	puntoRetorno.x = calcularCoordenada(this->t, p);
	p[0] = this->pControl[0].y ;
	p[1] = this->pControl[1].y ;
	p[2] = this->pControl[2].y ;
	p[3] = this->pControl[3].y ;
	puntoRetorno.y = calcularCoordenada(this->t, p);
	p[0] = this->pControl[0].z ;
	p[1] = this->pControl[1].z ;
	p[2] = this->pControl[2].z ;
	p[3] = this->pControl[3].z ;
	puntoRetorno.z = calcularCoordenada(this->t, p);
	this->t = this->t + 1/this->divisiones;
//	cout << puntoRetorno.x << " " << puntoRetorno.y << " " << puntoRetorno.z << endl;


return puntoRetorno;
}

float* CurvaBessier::getControl() const {
	return tControl;
}

float CurvaBessier::calcularCoordenada(float t, float p[4]) {
	float punto = 0;
		punto += (-pow(t, 3) + 3 * pow(t, 2) - 3 * t + 1) * p[0];
		punto += (3 * pow(t, 3) - 6 * pow(t, 2) + 3 * t) * p[1];
		punto += (-3 * pow(t, 3) + 3 * pow(t, 2)) * p[2];
		punto += (pow(t, 3)) * p[3];

		if (contAux % 3 == 0){
		tangAux.x += (-3*t * t+6*t-3) * p[0];
		tangAux.x += (9* t * t -6*t+3)* p[1];
		tangAux.x += (-9* t * t+6*t)* p[2];
		tangAux.x += (-3* t * t)* p[3];}
		if (contAux % 3 == 1){
		tangAux.y += (-3*t * t+6*t-3) * p[0];
		tangAux.y += (9* t * t -6*t+3)* p[1];
		tangAux.y += (-9* t * t+6*t)* p[2];
		tangAux.y += (-3* t * t)* p[3];}
		if (contAux % 3 == 2){
		tangAux.z += (-3*t * t+6*t-3) * p[0];
		tangAux.z += (9* t * t -6*t+3)* p[1];
		tangAux.z += (-9* t * t+6*t)* p[2];
		tangAux.z += (-3* t * t)* p[3];}

//		cout << contAux << endl;

		contAux++;
		if(contAux % 3 == 0)
		{
			tControl[it] = tangAux.x;
			it++;
			tControl[it] = tangAux.y;
			it++;
			tControl[it] = tangAux.z;
			it++;
			tangAux.x = 0;
			tangAux.y = 0;
			tangAux.z = 0;
//			cout << it << endl;
//			cout << contAux << endl;
//			contAux= 0;
		}

		return punto;
}

vector<glm::vec3> CurvaBessier::obtenerPuntos() {
	vector<glm::vec3> vectorRetorno;

	while(this->t <= 1)
	{
//		cout << this->t << endl;
		vectorRetorno.push_back(proximoPunto());
	}

	return vectorRetorno;
}
